<?php

namespace BridgePattern;

/**
 * 桥接模式的角色和职责
 * 抽象化(Abstraction):定义抽象的接口，同时维护一个对实现化对象(Implementor)的引用。
 * 扩展抽象化(Refined Abstraction):在抽象化基础上扩展，调用实现化对象的方法，增加新的功能。
 * 实现化(Implementor):定义实现化角色的接口，它不需要与抽象化接口完全一样，但一般要提供基本操作。
 * 具体实现化(ConcreteImplementor):真正去实现实现化接口的类，完成具体的业务逻辑。
 */
/**
 * 说人话，以发送消息为例：发送方式(微信、短信、邮件等)和消息(普通消息，加急消息，物流消息等)
 * 可以将发送方式作为抽象接口
 * 在消息的抽象类中引用发送方式的实例，从而实现解耦
 */

// 1. 定义发送方式接口：表示消息发送的底层实现渠道
interface MessageSeeder
{
    public function send(string $content): void;
}

// 2. 实现MessageSeeder，定义多种实例(微信、短信、邮件)
class WechatMessageSeeder implements MessageSeeder
{
    public function send(string $content): void
    {
        echo "通过【微信】发送消息：$content";
    }
}

class SmsMessageSeeder implements MessageSeeder
{
    public function send(string $content): void
    {
        echo "通过【短信】发送消息：$content";
    }
}

class EmailMessageSeeder implements MessageSeeder
{
    public function send(string $content): void
    {
        echo "通过【邮件】发送消息：$content";
    }
}
// 3. 发送消息的抽象类，包含了对发送方式的引用
abstract class Message
{
    protected MessageSeeder $messageSeeder;

    /**
     * @param MessageSeeder $messageSeeder
     */
    public function __construct(MessageSeeder $messageSeeder)
    {
        $this->messageSeeder = $messageSeeder;
    }

    public function send($content): void
    {

    }
}

// 4. 实现不同的消息类型:定义业务维度的扩展
class NormalMessage extends Message
{
    public function send($content): void
    {
        echo "【正常消息发送】\n";
        $this->messageSeeder->send($content);
    }
}

class UrgentMessage extends Message
{
    public function send($content): void
    {
        echo "【加急消息发送】\n";
        $this->messageSeeder->send("【加急】$content");
    }
}

// 后续有其他的消息，实现抽象类即可
// TODO 物流信息...

$emailMessageSeeder = new EmailMessageSeeder();
$wechatMessageSeeder = new WechatMessageSeeder();
$smsMessageSeeder = new SmsMessageSeeder();
// 普通邮件消息
$normalEmailMessage = new NormalMessage($emailMessageSeeder);
$normalEmailMessage->send("欢迎使用我们的系统！\n");
// 普通微信消息
$normalWechatMessage = new NormalMessage($wechatMessageSeeder);
$normalWechatMessage->send("服务器 CPU 负载率过高！！\n");
// 加急短信消息
$urgentSmsMessage = new UrgentMessage($smsMessageSeeder);
$urgentSmsMessage->send("数据库连接异常！！\n");
